﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management.Automation.Runspaces;
using Citrix.Management.Automation;

namespace Citrix.XaAdminMobile.Model
{
    /// <summary>
    /// This is our default implementation of IModelBase that uses the Citrix SDK to query all
    /// its state.
    /// </summary>
    class DefaultModel : IModelBase
    {
        /// <summary>
        /// The source for all our server state.
        /// </summary>
        private readonly ServersModel servers;

        /// <summary>
        /// The source for all our session state.
        /// </summary>
        private readonly SessionsModel sessions;

        /// <summary>
        /// Holds the config of which XenApp server we talk to using the SDK.
        /// </summary>
        private readonly ServerConfigModel serverConfig;

        /// <summary>
        /// Tracks disposed status.
        /// </summary>
        private bool disposed = false;

        /// <summary>
        /// Initialisation ctor.
        /// </summary>
        public DefaultModel()
        {
            this.RunspacePool = CitrixRunspaceFactory.DefaultRunspacePool;
            this.serverConfig = new ServerConfigModel(this);
            this.servers = new ServersModel(this);
            this.sessions = new SessionsModel(this);
        }

        /// <summary>
        /// Finalizer.
        /// </summary>
        ~DefaultModel()
        {
            OnDispose();
        }

        /// <summary>
        /// The name of the server hosting the XenApp SDK endpoint that we use for all our SDK
        /// queries. This is used as the "-ComputerName" parameter.
        /// </summary>
        public string ConnectionTarget
        {
            get { return this.serverConfig.ServerName; }
        }

        /// <summary>
        /// Returns the PowerShell runspace pool we use to execute PS commands to query the
        /// XenApp SDK. All model objects must use this pool so we know which pool to cleanup
        /// at app shutdown (since any runspaces not cleaned up will block app shutdown).
        /// </summary>
        public RunspacePool RunspacePool
        {
            get;
            private set;
        }

        /// <summary>
        /// The server config model object.
        /// </summary>
        public IServerConfigModel ServerConfig
        {
            get { return this.serverConfig; }
        }

        /// <summary>
        /// Gets the model object for querying XenApp server state.
        /// </summary>
        public IServersModel Servers
        {
            get { return this.servers; }
        }

        /// <summary>
        /// Gets the session model object provider.
        /// </summary>
        public ISessionsModel Sessions
        {
            get { return this.sessions; }
        }

        /// <summary>
        /// IDisposable implementation.
        /// </summary>
        public void Dispose()
        {
            OnDispose();
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Dipose handler.
        /// </summary>
        private void OnDispose()
        {
            if (!this.disposed)
            {
                this.disposed = true;
                this.RunspacePool.Dispose();
            }
        }
    }
}
